package org.example.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.example.entity.LoanOverdueStatistics;
import org.example.service.LoanOverdueStatisticsExcelService;
import org.example.service.LoanOverdueStatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;

/**
 * 贷款逾期统计Excel导入导出服务实现类
 */
@Slf4j
@Service
public class LoanOverdueStatisticsExcelServiceImpl implements LoanOverdueStatisticsExcelService {
    
    @Autowired
    private LoanOverdueStatisticsService loanOverdueStatisticsService;

    /**
     * 每隔5000条存储数据库，实际使用中可以3000条，然后清理list，方便内存回收
     */
    private static final int BATCH_COUNT = 5000;

    @Override
    public int importExcel(MultipartFile file) throws IOException {
        final java.util.List<LoanOverdueStatistics> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        final int[] totalCount = {0};

        EasyExcel.read(file.getInputStream(), LoanOverdueStatistics.class, new ReadListener<LoanOverdueStatistics>() {
            @Override
            public void invoke(LoanOverdueStatistics data, AnalysisContext context) {
                // 设置创建和更新时间
                data.setCreatedAt(LocalDateTime.now());
                data.setUpdatedAt(LocalDateTime.now());

                cachedDataList.add(data);

                // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
                if (cachedDataList.size() >= BATCH_COUNT) {
                    saveData();
                    // 存储完成清理 list
                    cachedDataList.clear();
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                // 这里也要保存数据，确保最后遗留的数据也存储到数据库
                saveData();
                log.info("Excel导入完成，共处理 {} 条数据", totalCount[0]);
            }

            private void saveData() {
                if (!cachedDataList.isEmpty()) {
                    loanOverdueStatisticsService.batchSave(new ArrayList<>(cachedDataList));
                    totalCount[0] += cachedDataList.size();
                    log.info("已保存 {} 条数据", cachedDataList.size());
                }
            }
        }).sheet().doRead();

        return totalCount[0];
    }

    @Override
    public void exportExcel(HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("贷款逾期统计_全部", StandardCharsets.UTF_8);
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        java.util.List<LoanOverdueStatistics> dataList = loanOverdueStatisticsService.getAllData();
        EasyExcel.write(response.getOutputStream(), LoanOverdueStatistics.class).sheet("贷款逾期统计").doWrite(dataList);
    }

    @Override
    public void exportExcelByLoanType(String loanType, HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("贷款逾期统计_" + loanType, StandardCharsets.UTF_8);
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        java.util.List<LoanOverdueStatistics> dataList = loanOverdueStatisticsService.getByLoanType(loanType);
        EasyExcel.write(response.getOutputStream(), LoanOverdueStatistics.class).sheet("贷款逾期统计").doWrite(dataList);
    }

    @Override
    public void exportExcelByDimension(String dimension, HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("贷款逾期统计_" + dimension, StandardCharsets.UTF_8);
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        java.util.List<LoanOverdueStatistics> dataList = loanOverdueStatisticsService.getByDimension(dimension);
        EasyExcel.write(response.getOutputStream(), LoanOverdueStatistics.class).sheet("贷款逾期统计").doWrite(dataList);
    }
}
